<template>
    <view><canvas canvas-id="mSetimg" :style="{width: canvasWH.width + 'px', height: canvasWH.height + 'px'}" class="my-canvas"
            disable-scroll="false"></canvas></view>
</template>

<script>
    export default {
        props: {
            type: {
                type: Number,
                default: 1
            },
            canvasWH: {
                type: Object,
                default: function() {
                    return {
                        width: 750,
                        height: 1334,
                        bgcolor: ''
                    }
                }
            }
        },
        created() {
            this.ctxCanvas = uni.createCanvasContext('mSetimg', this);
        },
        methods: {
            haibao(calData, callback) {
                uni.showLoading({
                    title: '加载中', //文字
                    mask: true //是否全局遮罩
                })
                this.image('mSetimg', calData.imgList, calData.textList, callback);
            },
            image(canvasId, imgList, textList, callback) {
                let _that = this;
                let ctx = this.ctxCanvas;
                let promiseAll = [];
                for (let v of imgList) {
                    promiseAll.push(this.downloadImg(v));
                }
                Promise.all(promiseAll)
                    .then(res => {
                        for (let i = 0; i < res.length; i++) {
                            this.drawImg(imgList[i], res[i]);
                        }
                        this.setFont(textList);
                        ctx.draw(false, res => {
                            setTimeout(() => {
                                uni.canvasToTempFilePath({
                                        canvasId: canvasId,
                                        width: _that.canvasWH.width,
                                        height: _that.canvasWH.height,
                                        destWidth: _that.canvasWH.width,
                                        destHeight: _that.canvasWH.height,
                                        quality: 1,
                                        success: function(res) {
                                            callback(res.tempFilePath);
                                        },
                                        fail: function(res) {
                                            console.log(JSON.stringify(res));
                                        },
                                        complete: res => {
                                            uni.hideLoading();
                                        }
                                    },
                                    this
                                );
                            }, 200);
                        });
                    })
                    .catch(() => {
                        uni.hideLoading();
                    });
            },
            // 获取网络图片
            downloadImg(item) {
                return new Promise((resolve, reject) => {
                    uni.downloadFile({
                        url: item.u,
                        success: res => {
                            if (res.statusCode === 200) {
                                resolve(res);
                            }
                        },
                        fail: (err) => {
                            uni.showModal({
                                content: `${JSON.stringify(item)}`
                            })
                            uni.showToast({
                                title: '网络异常，请重试',
                                icon: 'none'
                            });
                            reject(err);
                        }
                    });
                });
            },
            // 绘图
            drawImg(item, res) {
                let ctx = this.ctxCanvas;
                if (item.PI) {
                    ctx.save();
                    ctx.beginPath();
                    ctx.arc(item.x + item.w / 2, item.y + item.w / 2, item.w / 2, 0, 2 * Math.PI);
                    ctx.stroke();
                    ctx.clip();
                    ctx.drawImage(res.tempFilePath, item.x, item.y, item.w, item.h);
                    ctx.restore();
                } else {
                    if (item.circle) {
                        ctx.save();
                        ctx.beginPath();
                        ctx.arc(item.x + item.w / 2, item.y + item.h / 2, item.r, 0, 2 * Math.PI);
                        ctx.setStrokeStyle('#E9E9E9');
                        ctx.stroke();
                        ctx.clip();
                        ctx.drawImage(res.tempFilePath, item.x, item.y, item.w, item.h);
                        ctx.restore();
                    } else {
                        ctx.drawImage(res.tempFilePath, item.x, item.y, item.w, item.h);
                    }
                }
            },
            //绘制文字
            setFont(arr) {
                let _this = this;
                let ctx = this.ctxCanvas;
                let s = 20 * this.scale; //默认字体大小
                let f = 'normal normal 20px/20px sans-serif';
                arr.forEach((item, index) => {
                    ctx.setTextBaseline('top');
                    ctx.font = item.f || f;
                    ctx.setFontSize(item.s || s);
                    ctx.setTextAlign(item.setTextAlign || 'left');
                    ctx.setFillStyle(item.strokeStyle || '#000000');
                    if (item.setShadow) {
                        ctx.setShadow(...item.setShadow);
                    } else {
                        ctx.setShadow(0, 0, 0, '#000000');
                    }
                    let textWidth = this.getStringWidth(item.t, item.s || s);
                    if (item.maxWidth) {
                        if (textWidth <= item.maxWidth) {
                            ctx.fillText(item.t, item.x, item.y);
                        } else {
                            this.wordWrap(item.t, item.s, item.x, item.y, item.maxWidth);
                        }
                    } else {
                        ctx.fillText(item.t, item.x, item.y);
                    }
                    if (item.lineThrough) {
                        this.drawLineThrough(item.x, item.y, textWidth, '#989898', item.s || s);
                    }
                    if (item.b) {
                        item.b.bind(_this)({
                            x: item.x / 1 + 5,
                            y: item.y,
                            w: textWidth
                        });
                    }
                });
            },
            // 绘制文字换行
            wordWrap(t, s, x, y, m) {
                let chr = t.split(''); // 分割为字符串数组
                let temp = '';
                let row = [];
                for (let a = 0; a < chr.length; a++) {
                    let tempWidth = this.getStringWidth(temp, s);
                    if (tempWidth < m) {
                        temp += chr[a];
                    } else {
                        a--;
                        row.push(temp);
                        temp = '';
                    }
                }
                row.push(temp);
                for (var b = 0; b < row.length; b++) {
                    if (b < row.length) {
                        this.ctxCanvas.fillText(row[b], x, y + b * s * 1.5);
                    }
                }
            },
            // 获取文本宽度兼容方法
            measureTextWidth(t, s) {
                t = String(t);
                let arr = t.split('');
                let width = 0;
                arr.forEach(function(item) {
                    if (/[a-zA-Z]/.test(item)) {
                        width += 7;
                    } else if (/[0-9]/.test(item)) {
                        width += 5.5;
                    } else if (/\./.test(item)) {
                        width += 2.7;
                    } else if (/-/.test(item)) {
                        width += 3.25;
                    } else if (/[\u4e00-\u9fa5]/.test(item)) {
                        //中文匹配
                        width += 10;
                    } else if (/\(|\)/.test(item)) {
                        width += 3.73;
                    } else if (/\s/.test(item)) {
                        width += 2.5;
                    } else if (/%/.test(item)) {
                        width += 8;
                    } else if (/#|¥/.test(item)) {
                        width += 6.4;
                    } else if (/\?|\*/.test(item)) {
                        width += 4.9;
                    } else if (/\!|\_/.test(item)) {
                        width += 4.5;
                    } else if (/\+|\=|\^|~/.test(item)) {
                        width += 7.7;
                    } else if (/\[|\]/.test(item)) {
                        width += 3.9;
                    } else if (/:/.test(item)) {
                        width += 2.9;
                    } else {
                        width += 10;
                    }
                });
                return (width * s) / 10;
            },
            // 获取文字长度兼容写法
            getStringWidth(t, s) {
                let textWidth = 0;
                try {
                    textWidth = this.ctxCanvas.measureText(t).width || this.measureTextWidth(t, s);
                } catch (err) {
                    textWidth = s * t.length;
                }
                return textWidth;
            },
            // 绘制线条
            drawLineThrough(x, y, w, color, size) {
                let top = 0;
                let ctx = this.ctxCanvas;
                // #ifdef APP-PLUS
                top = y / 1 + size / 2 + 1;
                // #endif
                // #ifndef APP-PLUS
                top = y / 1 + size / 2;
                // #endif
                ctx.beginPath();
                ctx.setLineWidth(1);
                ctx.moveTo(x, top);
                ctx.lineTo(x + w, top);
                ctx.setStrokeStyle(color);
                ctx.stroke();
            }
        }
    };
</script>

<style lang="scss" scoped>
    .my-canvas {
        position: fixed;
        top: 10000px;
        left: 10000px;
        width: 750px;
        height: 1334px;
    }
</style>
